package com.mineoj.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mineoj.common.ErrorCode;
import com.mineoj.exception.BusinessException;
import com.mineoj.model.entity.User;
import com.mineoj.model.entity.UserFollow;
import com.mineoj.model.entity.User;
import com.mineoj.model.entity.UserFollow;
import com.mineoj.service.UserService;
import com.mineoj.service.UserFollowService;
import com.mineoj.service.UserFollowService;
import com.mineoj.mapper.UserFollowMapper;
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
* @author 明月
* @description 针对表【user_follow(用户关注)】的数据库操作Service实现
* @createDate 2025-04-12 23:52:00
*/
@Service
public class UserFollowServiceImpl extends ServiceImpl<UserFollowMapper, UserFollow>
    implements UserFollowService{
    @Resource
    private UserService userService;

    /**
     * 关注
     *
     * @param followUserId
     * @param loginUser
     * @return
     */
    @Override
    public int doUserFollow(long followUserId, User loginUser) {
        // 判断实体是否存在，根据类别获取实体
        User user = userService.getById(followUserId);
        if (user == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        // 是否已关注
        long userId = loginUser.getId();
        // 每个用户串行关注
        // 锁必须要包裹住事务方法
        UserFollowService userFollowService = (UserFollowService) AopContext.currentProxy();
        synchronized (String.valueOf(userId).intern()) {
            return userFollowService.doUserFollowInner(userId, followUserId);
        }
    }

    /**
     * 封装了事务的方法
     *
     * @param userId
     * @param userId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int doUserFollowInner(long userId, long followUserId) {
        UserFollow userFollow = new UserFollow();
        userFollow.setUserId(userId);
        userFollow.setFollowUserId(followUserId);
        QueryWrapper<UserFollow> thumbQueryWrapper = new QueryWrapper<>(userFollow);
        UserFollow oldUserFollow = this.getOne(thumbQueryWrapper);
        boolean result;
        // 已关注
        if (oldUserFollow != null) {
            result = this.remove(thumbQueryWrapper);
            if (result) {
                // 用户关注数 - 1
                result = userService.update()
                        .eq("id", userId)
                        .gt("followNum", 0)
                        .setSql("followNum = followNum - 1")
                        .update();
                // 被关注用户粉丝数 - 1
                result &= userService.update()
                        .eq("id", followUserId)
                        .gt("fanNum", 0)
                        .setSql("fanNum = fanNum - 1")
                        .update();
                return result ? -1 : 0;
            } else {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR);
            }
        } else {
            // 未关注
            result = this.save(userFollow);
            if (result) {
                // 用户关注数 + 1
                result = userService.update()
                        .eq("id", userId)
                        .setSql("followNum = followNum + 1")
                        .update();
                // 被关注用户粉丝数 + 1
                result &= userService.update()
                        .eq("id", followUserId)
                        .setSql("fanNum = fanNum + 1")
                        .update();
                return result ? 1 : 0;
            } else {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR);
            }
        }
    }


}




